import { ref, App } from "vue";
interface OnMessageInterface {
  data?: object;
}

const WebSocketPlugin = {
  install(app: App) {
    let ws = ref<any>(null);
    let message = ref<any>(null);
    let callback = ref<any>(null);
    const wsUrl = ref<any>(null);
    //避免ws重复连接
    const lockReconnect = ref(false);
    const connect = (url: string) => {
      wsUrl.value = url;
      try {
        if ("WebSocket" in window) {
          ws.value = new WebSocket(url);
          ws.value.onopen = () => {
            //心跳检测重置
            heartCheck.reset().start();
            ws.value.send(
              JSON.stringify({
                token: localStorage.getItem("token"),
              })
            );
            sendAndMessage();
          };
          ws.value.onmessage = (event: OnMessageInterface) => {
            //拿到任何消息都说明当前连接是正常的
            heartCheck.reset().start();
            callback.value && callback.value(event.data);
          };
          ws.value.onclose = () => {
            ws.value === null;
            reconnect(url);
          };
          ws.value.onerror = () => {
            ws.value = null;
            reconnect(url);
          };
        }
      } catch (e) {
        reconnect(url);
      }
    };

    const reconnect = (url: string) => {
      if (lockReconnect.value) {
        return;
      }
      lockReconnect.value = true;
      setTimeout(function () {
        connect(url);
        lockReconnect.value = false;
      }, 2000);
    };
    // 关闭
    const close = () => {
      if (ws.value && ws.value.readyState !== WebSocket.CLOSED) {
        ws.value = null;
        message.value = null;
        callback.value = null;
      }
    };

    //发送消息初始化
    const sendAndMessage = () => {
      if (ws.value?.readyState === WebSocket.OPEN && message.value) {
        ws.value.send(JSON.stringify(message.value));
      } else if (ws.value?.readyState !== WebSocket.CONNECTING) {
        reconnect(wsUrl.value);
      }
    };
    //页面初始化方法
    const init = (msg: object, cb: any) => {
      message.value = msg;
      callback.value = cb;
      sendAndMessage();
    };
    //心跳检测
    const heartCheck = {
      //这里设置10分钟发一次心跳
      timeout: 10 * 60 * 1000,
      timeoutObj: null as any,
      reset: function () {
        clearTimeout(this.timeoutObj);
        return this;
      },
      start: function () {
        this.timeoutObj && clearTimeout(this.timeoutObj);
        this.timeoutObj = setTimeout(function () {
          //检测状态
          sendAndMessage();
        }, this.timeout);
      },
    };
    app.provide("wsInit", init);
    app.provide("wsClose", close);
    app.provide("wsConnect", connect);
  },
};
export default WebSocketPlugin;
